package com.lib.common.adapter;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.lib.common.R;
import com.lib.utils.XLog;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 一叶丶枫凌
 * Created on 2020-06-25
 */
public abstract class BaseMultiItemRecyclerAdapter<ADAPTER, DATA> extends RecyclerView.Adapter<BaseMultiItemRecyclerAdapter.BaseViewHolder<ADAPTER, DATA>> {
    private List<DATA> mDataList = new ArrayList<>();
    private Context mContext;
    private int mBaseLayoutResId;
    protected View.OnClickListener mOnClickListener;
    protected View.OnLongClickListener mOnLongClickListener;

    public BaseMultiItemRecyclerAdapter(Context context, int baseLayoutResId) {
        mContext = context;
        mBaseLayoutResId = baseLayoutResId;
    }

    public View.OnClickListener getOnClickListener() {
        return mOnClickListener;
    }

    public void setOnClickListener(View.OnClickListener l) {
        mOnClickListener = l;
    }

    public View.OnLongClickListener getOnLongClickListener() {
        return mOnLongClickListener;
    }

    public void setOnLongClickListener(View.OnLongClickListener l) {
        mOnLongClickListener = l;
    }

    abstract protected Class<? extends BaseViewHolder<ADAPTER, DATA>> onBindViewTypeToViewHolder(int viewType);

    @NonNull
    @Override
    final public BaseViewHolder<ADAPTER, DATA> onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        Class<? extends BaseViewHolder<ADAPTER, DATA>> clazz = onBindViewTypeToViewHolder(viewType);
        if (clazz == null) {
            XLog.w("未绑定的viewType：" + viewType);
        }
        try {
            View view = null;
            if (mBaseLayoutResId > 0) {
                view = LayoutInflater.from(mContext).inflate(mBaseLayoutResId, parent, false);
            }

            Constructor<? extends BaseViewHolder<ADAPTER, DATA>> declaredConstructor = clazz.getDeclaredConstructor(View.class);
            declaredConstructor.setAccessible(true);
            BaseViewHolder<ADAPTER, DATA> baseViewHolder = declaredConstructor.newInstance(view);
            baseViewHolder.onCreate(mContext, (ADAPTER) this);
            return baseViewHolder;
        } catch (Throwable e) {
            XLog.w("catch info->" + Log.getStackTraceString(e));
            //            如果这里异常了，可以换成对应的ViewHolder进行测试
            //            baseViewHolder = new ViewHolder(view, mContext, this);
            return getUnknownViewHolder(parent, mContext);
        }
    }

    /**
     * 可通过覆写实现不同的未知布局
     */
    protected BaseViewHolder<ADAPTER, DATA> getUnknownViewHolder(ViewGroup parent, Context context) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.jmsg_view_holder_unkown, parent, false);
        UnknownViewHolder holder = new UnknownViewHolder(view);
        holder.onCreate(context, this);
        return holder;
    }

    @Override
    final public void onBindViewHolder(@NonNull BaseViewHolder<ADAPTER, DATA> holder, int position) {
        DATA data = getData(position);
        boolean bindData = onBindViewHolder(data, position);
        if (!bindData) {
            holder.onBindViewHolder(data, position);
        }
    }

    protected boolean onBindViewHolder(DATA data, int position) {
        return false;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    final public DATA getData(int adapterPosition) {
        DATA baseData = null;
        try {
            baseData = mDataList.get(adapterPosition);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return baseData;
    }

    final public List<DATA> getData() {
        return mDataList;
    }

    @Override
    final public int getItemCount() {
        return mDataList.size();
    }

    final public void setData(List<DATA> list) {
        if (list == null || list.size() == 0) {
            return;
        }
        mDataList.clear();
        mDataList.addAll(list);
        notifyDataSetChanged();
    }

    final public void addData(DATA data) {
        if (data == null) {
            return;
        }
        int start = mDataList.size();
        mDataList.add(data);

        notifyItemInserted(start);
        notifyItemRangeChanged(start, start + 1);
    }

    final public void addData(List<DATA> list) {
        if (list == null) {
            return;
        }
        int addSize = list.size();
        if (addSize == 0) {
            return;
        }
        int start = mDataList.size();
        mDataList.addAll(list);

        notifyItemRangeInserted(start, addSize);
        notifyItemRangeChanged(start, start + addSize);
    }

    final public void clear() {
        mDataList.clear();
        notifyDataSetChanged();
    }

    public static abstract class BaseViewHolder<ADAPTER, DATA> extends RecyclerView.ViewHolder {
        protected Context mContext;
        protected ADAPTER mAdapter;

        public BaseViewHolder(View view) {
            super(view);
        }

        final public void onCreate(Context context, ADAPTER adapter) {
            mContext = context;
            mAdapter = adapter;
        }

        public abstract void onBindViewHolder(DATA data, int position);
    }

    public static class UnknownViewHolder extends BaseViewHolder {

        public UnknownViewHolder(View view) {
            super(view);
        }

        @Override
        public void onBindViewHolder(Object data, int position) {

        }
    }
}